package org.ourguy.mymoviesandshows.datamodel;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;

/**
 * Movie abstract data type
 * @author n.sobadjiev
 */
public class Movie implements ITitle {

	
	@SuppressWarnings("unused")
	private static final long serialVersionUID = 1L;
	/**
	 * The title of the movie
	 */
	private String title;
	
	/**
	 * The release date of the title
	 */
	private java.util.Date releaseDate;
	
	/**
	 * The URL of the title
	 */
	private URL url;
	
	/**
	 * The URL of the trailer for the movie
	 */
	private URL trailerURL;
	
	/**
	 * The runtime of the title
	 */
	private int runtime;
	
	/**
	 * The plot summary of the title
	 */
	private String plot;
	
	/**
	 * The IMDb ID of the title
	 */
	private String imdbId;
	
	/**
	 * The API-Specific ID of the title
	 */
	private String apiId;
	
	/**
	 * Cover art for the title
	 */
	private ICoverArt coverArt;
	
	/**
	 * Genre list for the title
	 */
	private String[] genre;
		
	/**
	 * Watched flag for the title
	 */
	private boolean watched;
	
	/**
	 * Favourite flag for the title
	 */
	private boolean favorite;

	/**
	 * Cast of the title
	 */
	private Cast cast;
	
	/**
	 * Title rating
	 */
	private float rating;
	
	/**
	 * Tracking list indicator.
	 */
	private boolean tracked;

	/**
	 * Instantiate a new movie by API-Specific ID and a title
	 * @param apiId API-Specific ID
	 * @param title Title
	 */
	public Movie(String apiId, String title){
		this.apiId = apiId;
		this.title = title;
	}
	
	public Movie(){}
	
	/**
	 * Instantiate a new movie by API-Specific ID, a title and plot
	 * @param apiId API-Specific ID
	 * @param title the title
	 * @param plot the plot of the title
	 */
	public Movie(String apiId, String title, String plot){
		this.apiId = apiId;
		this.title = title;
		this.plot = plot;
	}

	/**
	 * Set the external link of the title
	 * @param newLink
	 */
	public void setExternalLink(java.net.URL newLink) {
		this.url = newLink;
	}


	/**
	 * Set the URL of the trailer for the title
	 * @param url
	 */
	public void setTrailer(URL url) {
		this.trailerURL = url;
	}

	/**
	 * Re-set the title
	 * @param title the title to set
	 */
	public void setTitle(String title) {
		this.title = title;
	}
	
	public void setImdbId(String imdbId) {
		this.imdbId = imdbId;
	}

	public void setReleaseDate(Date date) {
		releaseDate = date;
	}


	public void setCast(Cast cast) {
		this.cast = cast;
	}

	public void setPlot(String plot) {
		this.plot = plot;
	}


	public void setRating(float newRating) {
		rating = newRating;
	}
	
	public void setWatched() {
		watched = true;
	}

	public void setUnWatched() {
		watched = false;
	}
	
	/**
	 * @see Movie#setExternalLink
	 */
	public void setURL(URL url) {
		setExternalLink(url);
	}
	
	public void setRuntime(int runtime) {
		this.runtime = runtime;
	}
	
	public boolean isWatched(){
		return watched;
	}

	public void addToFavorites() {
		favorite = true;
	}

	public void removeFromFavorites() {
		favorite = false;
	}
	
	public boolean isInFavorites(){
		return favorite;
	}

	public URL getExternalLink() {
		return url;
	}

	/**
	 * Get the trailer of the title
	 */
	public URL getTrailer() {
		return trailerURL;
	}

	public String getTitle() {
		return title;
	}

	public String getImdbId() {
		return imdbId;
	}

	public Date getReleaseDate() {
		return releaseDate;
	}

	public String[] getGenre() {
		return genre;
	}

	public Cast getCast() {
		return cast;
	}

	public String getPlot() {
		return plot;
	}

	public float getRating() {
		return rating;
	}

	/**
	 * Get the url of the title
	 * @return
	 * @see Movie#getExternalLink()
	 */
	public URL getURL() {
		return url;
	}

	public int getRuntime() {
		return runtime;
	}

	/**
	 * Get the cover art of the title
	 * @return
	 */
	public ICoverArt getCoverArt() {
		return coverArt;
	}

	/**
	 * Set the cover art of the title by URL
	 * @param url
	 * @throws MalformedURLException
	 */
	public void setCoverArt(String url) throws MalformedURLException {
		this.coverArt = new CoverArtFromURL(url);
	}
	
	/**
	 * Set the cover art of the title by image
	 * @param image
	 */
	public void setCoverArt(android.graphics.Bitmap image) {
		this.coverArt = new CoverArtFromImage(image);
	}

	/**
	 * Get the list of genres for the title
	 * @param genres
	 */
	public void setGenreList(String ... genres) {
		this.genre = genres;
	}
	
	public void setGenre(String[] genre) {
		this.genre = genre;
	}
	
	/**
	 * @return the apiId
	 */
	public String getApiId() {
		return apiId;
	}

	/**
	 * @param apiId the apiId to set
	 */
	public void setApiId(String apiId) {
		this.apiId = apiId;
	}
	
	public boolean isTracked() {
		return this.tracked;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((apiId == null) ? 0 : apiId.hashCode());
		result = prime * result + ((imdbId == null) ? 0 : imdbId.hashCode());
		return result;
	}


	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Movie other = (Movie) obj;
		if (apiId == null) {
			if (other.apiId != null)
				return false;
		} else if (!apiId.equals(other.apiId))
			return false;
		if (imdbId == null) {
			if (other.imdbId != null)
				return false;
		} else if (!imdbId.equals(other.imdbId))
			return false;
		return true;
	}
	
	/* (non-Javadoc)
	 * @see ITitle#compareTo(ITitle)
	 */
	public int compareTo(ITitle title) {
		int result = this.title.compareTo(title.getTitle());
		if (result == 0)
			result = this.releaseDate.compareTo(title.getReleaseDate());
		return result;
	}

}
